const path = require('path')
const CompressionPlugin = require('compression-webpack-plugin')

function resolve(dir) {
  return path.join(__dirname, dir)
}

// vue.config.js
module.exports = {
  /*
    Vue-cli3:
    Crashed when using Webpack `import()` #2463
    https://github.com/vuejs/vue-cli/issues/2463
   */
  // 如果你不需要生产环境的 source map，可以将其设置为 false 以加速生产环境构建。
  productionSourceMap: false,
  // qiankuan打包时放开
  // outputDir: "../dist/main",
  // 多入口配置
  // pages: {
  //   index: {
  //     entry: 'src/main.js',
  //     template: 'public/index.html',
  //     filename: 'index.html',
  //   }
  // },
  // 打包app时放开该配置
  publicPath: '/',
  configureWebpack: config => {
    // 修复css-loader版本兼容性问题
    config.module.rules.forEach(rule => {
      if (rule.use) {
        rule.use.forEach(useEntry => {
          if (typeof useEntry === 'object' && useEntry.loader && useEntry.loader.includes('css-loader')) {
            useEntry.options = useEntry.options || {}
            useEntry.options.esModule = false
          }
        })
      }
    })

    // 生产环境取消 console.log
    if (process.env.NODE_ENV === 'production') {
      config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
    }

    // 生产环境优化配置
    if (process.env.NODE_ENV === 'production') {
      // 代码分割优化
      config.optimization = {
        ...config.optimization,
        splitChunks: {
          chunks: 'all',
          cacheGroups: {
            // 第三方库单独打包
            vendor: {
              name: 'chunk-vendors',
              test: /[\\/]node_modules[\\/]/,
              priority: 10,
              chunks: 'initial'
            },
            // Ant Design 单独打包
            antd: {
              name: 'chunk-antd',
              test: /[\\/]node_modules[\\/](@ant-design|antd)[\\/]/,
              priority: 20,
              chunks: 'all'
            },
            // ECharts 单独打包
            echarts: {
              name: 'chunk-echarts',
              test: /[\\/]node_modules[\\/](echarts|zrender)[\\/]/,
              priority: 20,
              chunks: 'all'
            },
            // 公共模块
            common: {
              name: 'chunk-common',
              minChunks: 2,
              priority: 5,
              chunks: 'all',
              reuseExistingChunk: true
            }
          }
        }
      }

      // 提高文件大小限制
      config.performance = {
        hints: 'warning',
        maxAssetSize: 1024 * 1024 * 2, // 2MB
        maxEntrypointSize: 1024 * 1024 * 5 // 5MB
      }

      // 修复文件名编码问题
      config.output = {
        ...config.output,
        filename: 'js/[name].[contenthash:8].js',
        chunkFilename: 'js/[name].[contenthash:8].js'
      }
    } else {
      config.output = {
        ...config.output,
        filename: 'js/[name].[hash:8].js',
        chunkFilename: 'js/[name].[hash:8].js'
      }
    }
  },
  chainWebpack: config => {
    config.resolve.alias
      .set('@$', resolve('src'))
      .set('@api', resolve('src/api'))
      .set('@assets', resolve('src/assets'))
      .set('@comp', resolve('src/components'))
      .set('@views', resolve('src/views'))

    // 修复css-loader版本兼容性问题
    try {
      config.module
        .rule('css')
        .test(/\.css$/)
        .oneOf('vue')
        .resourceQuery(/\?vue/)
        .use('css-loader')
        .tap(options => ({
          ...options,
          esModule: false
        }))
    } catch (e) {
      // 如果配置失败，忽略错误继续构建
      console.warn('CSS loader configuration warning:', e.message)
    }

    // 生产环境，开启js\css压缩
    if (process.env.NODE_ENV === 'production') {
      config.plugin('compressionPlugin').use(
        new CompressionPlugin({
          test: /\.(js|css|less)$/, // 匹配文件名
          threshold: 10240, // 对超过10k的数据压缩
          deleteOriginalAssets: false // 不删除源文件
        })
      )

      // 移除预加载插件，减少首屏加载
      config.plugins.delete('preload')
      config.plugins.delete('prefetch')

      // 优化图片资源
      config.module
        .rule('images')
        .use('url-loader')
        .tap(options => ({
          ...options,
          limit: 4096, // 小于4kb的图片转base64
          fallback: {
            loader: 'file-loader',
            options: {
              name: 'img/[name].[contenthash:8].[ext]'
            }
          }
        }))
    }

    // 配置 webpack 识别 markdown 为普通的文件
    config.module
      .rule('markdown')
      .test(/\.md$/)
      .use()
      .loader('file-loader')
      .end()

    // 编译vxe-table包里的es6代码，解决IE11兼容问题
    config.module
      .rule('vxe')
      .test(/\.js$/)
      .include.add(resolve('node_modules/vxe-table'))
      .add(resolve('node_modules/vxe-table-plugin-antd'))
      .end()
      .use()
      .loader('babel-loader')
      .end()

    // 编译fast-png等ES模块，解决ES6语法兼容问题
    config.module
      .rule('es6-modules')
      .test(/\.js$/)
      .include.add(resolve('node_modules/fast-png'))
      .add(resolve('node_modules/jspdf'))
      .end()
      .use('babel-loader')
      .loader('babel-loader')
      .options({
        presets: [
          ['@babel/preset-env', {
            targets: {
              browsers: ['> 1%', 'last 2 versions', 'not ie <= 10']
            }
          }]
        ],
        plugins: [
          '@babel/plugin-proposal-class-properties'
        ]
      })
      .end()
  },

  css: {
    loaderOptions: {
      less: {
        modifyVars: {
          /* less 变量覆盖，用于自定义 ant design 主题 */
          'primary-color': '#1890FF',
          'link-color': '#1890FF',
          'border-radius-base': '4px'
        },
        javascriptEnabled: true
      },
      css: {
        // 修复css-loader版本兼容性问题
        esModule: false
      }
    }
  },

  devServer: {
    port: 3000,
    host: '0.0.0.0',
    hot: true,
    disableHostCheck: true,
    overlay: {
      warnings: false,
      errors: true
    },
    headers: {
      'Access-Control-Allow-Origin': '*'
    },
    proxy: {
      /* 注意：jeecgboot前端做了改造，此处不需要配置跨域和后台接口（只需要改.env相关配置文件即可）
          issues/3462 很多人此处做了配置，导致刷新前端404问题，请一定注意 */
      '/jeecg-boot': {
        target: 'http://localhost:8080',
        ws: false,
        changeOrigin: true
      }
    }
  },

  lintOnSave: undefined
}
